package fr.asip.cps3.exemple.modele.traitements.fonctionsPKCS11.slotscartes;

import iaik.pkcs.pkcs11.wrapper.PKCS11;
import iaik.pkcs.pkcs11.wrapper.PKCS11Exception;

import java.util.LinkedHashMap;

import org.apache.log4j.Logger;

import fr.asip.cps3.exemple.modele.exceptions.ExceptionProgrammeExemple;
import fr.asip.cps3.exemple.modele.exceptions.ExceptionTraitement;
import fr.asip.cps3.exemple.modele.resultats.Resultat;
import fr.asip.cps3.exemple.modele.resultats.ResultatInfo;
import fr.asip.cps3.exemple.modele.traitements.util.TraitementsUtil;

/**
 * Classe de traitement : Obtention de la liste des slots
 *
 */
public class ListerSlots{

	/**
	 * Le loggeur
	 */
	private static Logger log = Logger.getLogger(ListerSlots.class);
	
	/**
	 * Renvoie le résultat de l'opération
	 * @param librairie Librairie PKCS#11 à utiliser
	 * @param avecCarte Booléen permetant de savoir si on liste que les slot avec cartes
	 * @return Résultat de l'opération
	 * @throws ExceptionTraitement 
	 */
	public static Resultat traitementP11(PKCS11 librairie,boolean avecCarte) throws ExceptionTraitement {

		try {
		
			if(librairie != null) {		
		
				ResultatInfo resultat;
				LinkedHashMap<String,String> infos = new LinkedHashMap<String,String>();
				
				if(avecCarte)
					resultat = new ResultatInfo("Liste les slots avec carte (C_GetSlotList)");
				else
					resultat = new ResultatInfo("Liste tous les slots (C_GetSlotList)");
				resultat.setInfos(infos);
				
				try {
					
					// Traitement à tester
					long[] slots = librairie.C_GetSlotList(avecCarte);
					
					// Formatage du résultat
					if(slots != null) {
						infos.put("Nombre de slots",Integer.toString(slots.length));
						for (int i = 0; i < slots.length; i++) {
							long slot = slots[i];
							resultat.getObjets().add(slot);
							infos.put("Identifiant de slot"+(i+1),Long.toString(slot));
						}
					} else {

						// Si la liste des slots retournée est nulle on lève l'exception
						log.error("La liste des slots retournee est nulle");
						if(avecCarte)
							throw new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_SLOTSCARTES_LISTE_SLOTS_AVEC_CARTE, "La liste des slots retournée est nulle");
						throw new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_SLOTSCARTES_LISTE_SLOTS_TOUS, "La liste des slots retournée est nulle");
						
					}
					
				} catch (PKCS11Exception e) {
					
					log.info("Operation echouee : "+TraitementsUtil.retranscritCodeRetour(e.getErrorCode()));
					resultat.setCodeRetour(e.getErrorCode());
					
				}
		
				return resultat;
				
			} else {
	
				// Si la librairie est nulle il est impossible de réaliser l'opération
				log.error("La librairie est nulle");
				if(avecCarte)
					throw new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_SLOTSCARTES_LISTE_SLOTS_AVEC_CARTE, "La librairie est nulle");
				throw new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_SLOTSCARTES_LISTE_SLOTS_TOUS, "La librairie est nulle");
			}
			
		} catch (Throwable t) {
			
			// Si une erreur Traitement a été rencontrée on lève l'exception
			if(t instanceof ExceptionTraitement)
				throw (ExceptionTraitement)t;
			
			// Si une erreur inattendue est survenue on la logue et on la lève
			log.error("Une erreur inattendue est survenue : "+ExceptionProgrammeExemple.getStacktrace(t));
			if(avecCarte)
					throw new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_SLOTSCARTES_LISTE_SLOTS_AVEC_CARTE, "Une erreur inattendue est survenue");			
			throw new ExceptionTraitement(ExceptionProgrammeExemple.TYPE_TRAITEMENT_SLOTSCARTES_LISTE_SLOTS_TOUS, "Une erreur inattendue est survenue");
			
		}
	}

}
